(function(angular) {
	'use strict';

	angular
		.module('xianwan')
	    .factory('ArrayUtil', ['$rootScope', 
	    	function($rootScope) {
	    		function findIndex(arr, obj, compareKey) {
	    			if (angular.isUndefined(arr)) {
	    				return -1;
	    			}
	    			for (let i = 0, len = arr.length; i < len; i++) {
						if (arr[i][compareKey] === obj[compareKey]) {
							return i;
						}    				
	    			}

	    			return -1;
	    		}

	    		function findSelectedIndex(arr, compareKey) {
	    			if (angular.isUndefined(arr)) {
	    				return -1;
	    			}
	    			for (let i = 0, len = arr.length; i < len; i++) {
						if (arr[i][compareKey] === true) {
							return i;
						}    				
	    			}

	    			return -1;	
	    		}

	            function findUnique(arrOld, arrNew, compareKey) {
	                let uniqueObj = {};
	                let arrNewAdd = [];
	                let arrRemoved = [];

	                if (!arrOld) {
	                	arrNewAdd = arrNew;
	                } else if (!arrNew) {
	                	arrRemoved = arrOld;
	                } else {
		                for (let i = 0, len = arrNew.length; i < len; i++) {
		                    if (findIndex(arrOld, arrNew[i], compareKey) === -1) {
		                        arrNewAdd.push(arrNew[i]);
		                    }
		                }

		                for (let i = 0, len = arrOld.length; i < len; i++) {
		                	if (findIndex(arrNew, arrOld[i], compareKey) === -1) {
		                		arrRemoved.push(arrOld[i]);
		                	}
		                }
	                }

	                uniqueObj.arrNewAdd = arrNewAdd;
	                uniqueObj.arrRemoved = arrRemoved;
	                return uniqueObj;
	            }

	            function pushArray(arrSrc, arrChild, compareKey) {
	            	let index = -1;

	            	arrChild.forEach(function(item) {
	            		index = findIndex(arrSrc, item, compareKey);
	            		if (index === -1) {
	            			arrSrc.push(item);
	            		}
	            	});
	            }

	            function popArray(arrSrc, arrChild, compareKey) {
	            	let index = -1;
	            	for(let i = 0, len = arrChild.length; i < len; i++) {
	            		if ((index = findIndex(arrSrc, arrChild[i], compareKey)) > -1) {
	            			arrSrc.splice(i, 1);
	            			// len--;
	            		} else {
	            			console.log('ArrayUtil:popArray:no-item-found');
	            		}
	            	}
	            }

	            /**
	             * 如果数组中有对应元素，则删除
	             * @param arrSrc: 源数组
	             * @param item: 查找的元素
	             * @param compareKey: 判断比对的字段
	             */
	            function popItem(arrSrc, item, compareKey) {
	            	let index = -1;

	            	for (let i = 0, len = arrSrc.length; i < len; i++) {
	            		index = findIndex(arrSrc, item, compareKey);
	            		if (index > -1) {
	            			arrSrc.splice(index, 1);
	            			break;
	            		}
	            	}
	            }

	            function isAllSelected(arr, fieldKey) {
	            	if (typeof arr === 'undefined') {
	            		return false;
	            	}

	            	for (let i = 0, len = arr.length; i < len; i++) {
	            		if (arr[i][fieldKey] !== true) {
	            			return false;
	            		}
	            	}

	            	return true;
	            }

		        function isSomeSelected(arr, fieldKey) {
		        	if (typeof arr === 'undefined') {
		        		return false;
		        	}

		        	for (let i = 0, len = arr.length; i < len; i++) {
		        		if (arr[i][fieldKey] === true) {
		        			return true;
		        		}
		        	}

		        	return false;
		        }

		        /**
		         * 切换数组所有项的选中情况
		         * @param items:需要切换的数组
		         * @param isSelected:是否选中
		         */
		        function toggleSelectItems(items, isSelected, arrExclude) {
		            if (typeof isSelected === 'undefined') {
		                isSelected = true;
		            }
		            items.forEach(function(item) {
		                item.selected = isSelected;
		            });
		        }

		        /**
		         * 切换数组中部分数组的选中情况
		         * @param items:需要切换的数组
		         * @param arrSelected:已选数组
		         * @param isSelected:是否选中
		         */
		        function toggleSelectOtherItems(items, arrSelected, isSelected) {
		        	if (typeof items === 'undefined') {
		        		return;
		        	}

		            if (typeof isSelected === 'undefined') {
		                isSelected = true;
		            }

		            let index = -1;
		            items.forEach(function(item) {
		                index = findIndex(arrSelected, item, 'user_id');
		                if (index > -1) {
		                    // arrSelected[index]['selected'] = isSelected;
		                    item['selected'] = isSelected;
		                }
		            });
		        }

		        /**
		         * 切换数组中单个元素的选中情况
		         */
		        function toggleSelectItem(item, selections, isSelected) {
		            if (typeof isSelected === 'undefined') {
		                isSelected = true;
		            }
		            let index = findIndex(selections, item, 'user_id');
		            if (index > -1) {
		            	selections[index]['selected'] = isSelected;
		            }
		        }

		        /**
		         * 数组中增加元素(类似于 concat，但是不重复添加)
		         * @param arrSrc:原数组
		         * @param items:需要增加的元素数组
		         */
		        function addItems(arrSrc, items) {
		        	let iIndex = -1;
		        	items.forEach(function(item, index) {
		        		iIndex = findIndex(arrSrc, item, 'user_id');
		        		if (iIndex === -1) {
		        			arrSrc.push(item);
		        		}
		        	})
		        }

		        /**
		         * 数组中删除元素
		         * @param arrSrc:原数组
		         * @param items:需要删除的元素数组
		         */
		        function removeItems(arrSrc, items) {
		        	let iIndex = -1;
		        	items.forEach(function(item, index) {
		        		iIndex = findIndex(arrSrc, item, 'user_id');
		        		if (iIndex > -1) {
		        			arrSrc.splice(iIndex, 1);
		        		}
		        	})
		        }

		        /**
		         * 判断数组是否包含关系
		         * @param  {[type]} arr        [description]
		         * @param  {[type]} arrChild   [description]
		         * @param  {[type]} compareKey [description]
		         */
		        function isArrContains(arr, arrChild, compareKey) {
		        	let index = -1;

		        	if (!angular.isArray(arr) || !angular.isArray(arrChild)) {
		        		return false;
		        	}
		        	
		        	for (let i = 0, len = arrChild.length; i < len; i++) {
		        		index = findIndex(arr, arrChild[i], compareKey);
		        		if (index === -1) {
		        			return false;
		        		}	
		        	}

		        	return true;
		        }

		        function isItemContains(arr, item, compareKey) {
		        	return findIndex(arr, item, compareKey) > -1;
		        }

		    	return {
		    		findIndex: findIndex, 
		    		findSelectedIndex: findSelectedIndex, 
	                findUnique: findUnique, 
	                pushArray: pushArray, 
	                popArray: popArray, 
	                popItem: popItem, 
	                isAllSelected: isAllSelected, 
	                isSomeSelected: isSomeSelected, 
	                toggleSelectItems: toggleSelectItems, 
	                toggleSelectOtherItems: toggleSelectOtherItems, 
	                toggleSelectItem: toggleSelectItem,
	                addItems: addItems, 
	                removeItems: removeItems, 
	                isArrContains: isArrContains,
	                isItemContains: isItemContains
		    	};
		    }
	    ]);
})(angular);